﻿using Dto;
using Dto.TeamBuy;
using Entity;
using Furion.EventBus;
using Services;
using System.Diagnostics;

namespace Events;

/// <summary>
/// 拼团事件处理类
/// </summary>
public class Teambuy : IEventSubscriber, ISingleton
{
    // 数据库访问对象
    private readonly ISqlSugarClient db;

    // 资金变动服务
    private readonly Logics.MoneyLogics money;

    // 通用服务
    private readonly Common com;

    private static SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);


    /// <summary>
    /// 构造函数，注入依赖服务
    /// </summary>
    public Teambuy(ISqlSugarClient db, Logics.MoneyLogics money, Common com, IEventPublisher pub)
    {
        this.db = db;
        this.money = money;
        this.com = com;
    }

    /// <summary>
    ///加入拼团
    /// </summary>
    [EventSubscribe("OrderComplete")]
    public async Task Join(EventHandlerContext e)
    {
        Stopwatch stopwatch = Stopwatch.StartNew();

        // 获取订单完成事件的数据
        var data = (Dto.OrderComplete)e.Source.Payload;

        // 获取订单信息
        var order = await com.GetOrder(data.OrderNo);

        // 检查订单类型是否为拼团返利
        if (order.OrderType != Entity.OrderType.拼团返利)
        {
            await db.Ado.CommitTranAsync();

            return;
        }

        //获取必要的参数
        var param = RedisHelper.HGet<JoinTeamBuyDto>("CreatedTeambuyParam", order.OrderNo);

        try
        {
            await semaphore.WaitAsync(); // 异步等待进入信号量

            //加入到一个拼团中
            var (teamBuy, product) = await RealJoinTeamBuy(order.UserId, param.ProductId, param.StoreId, order.ProxyId, param.ParentId);

            //非金币支付执行返佣逻辑
            if (data.PayType != PayType.金币) await Commission(product, teamBuy.Id, order.StoreId, order.ProxyId, order.UserId, param.ParentId, order.Id);

            order.ExtId = teamBuy.Id;

            await db.Updateable(order).ExecuteCommandAsync();
        }
        finally
        {
            semaphore.Release();
        }

        //释放缓存
        await RedisHelper.HDelAsync("CreatedTeambuyParam", order.OrderNo);

        stopwatch.Stop();

        Console.WriteLine("加入拼团用时:", stopwatch.ElapsedMilliseconds);
    }

    /// <summary>
    /// 真实加入拼团
    /// </summary>
    /// <param name="userId"></param>
    /// <param name="productId"></param>
    /// <param name="storeId"></param>
    /// <param name="proxyId"></param>
    /// <param name="parentId"></param>
    /// <returns></returns>
    private async Task<(Entity.TeamBuy, Entity.TeamBuyProduct)> RealJoinTeamBuy(int userId, int productId, int storeId, int proxyId, int parentId)
    {
        //获取参团人用户信息
        var userInfo = await db.Queryable<Entity.Client>().WithCache(1200).Select("name,avatar").FirstAsync(x => x.Id == userId);

        //获取商品信息
        var product = await db.Queryable<Entity.TeamBuyProduct>().WithCache(1200).FirstAsync(x => x.Id == productId);

        //获取一个进行中的人员不满的商户拼团
        var teamBuy = await db.Queryable<Entity.TeamBuy>().FirstAsync(x => x.StoreId == storeId && x.CurrentNum < 5 && x.State == TeamBuyState.进行中);

        //没有满足条件的拼团,创建一个新的拼团
        if (teamBuy == null)
        {
            teamBuy = new Entity.TeamBuy
            {
                CratedUserId = storeId,

                Created = DateTime.Now,

                CurrentNum = 0,

                Description = product.Description,

                GroupPrice = product.GourpPrice,

                JoinRobot = false,

                MaxNum = 7,

                ProductId = productId,

                StoreId = storeId,

                ProxyId = proxyId,

                Title = product.Name,

                State = TeamBuyState.进行中
            };

            teamBuy.Id = await db.Insertable(teamBuy).ExecuteReturnIdentityAsync();
        }
        else
        {
            teamBuy.CurrentNum += 1;

            await db.Updateable(teamBuy).ExecuteCommandAsync();
        }

        // 创建拼团记录
        var log = new TeamBuyLog
        {
            Avatar = userInfo.Avatar,

            NickName = userInfo.Name,

            IsRobot = false,

            StoreId = storeId,

            ProxyId = proxyId,

            UserId = userId,

            TeamBuyId = teamBuy.Id,

            JoinTime = DateTime.Now
        };

        //拼团推荐信息
        var reference = new Entity.TeamBuyReference
        {
            TeamBuyId = teamBuy.Id,

            UserId = userId,

            ParnentId = parentId,

            StoreId = storeId,

            ProxyId = proxyId
        };

        //记录邀请人信息
        await db.Insertable(reference).ExecuteCommandAsync();

        //添加拼团信息
        await db.Insertable(log).ExecuteCommandAsync();

        return (teamBuy, product);
    }

    /// <summary>
    /// 拼团返佣
    /// </summary>
    /// <param name="e"></param>
    /// <param name="teamBuyId"></param>
    /// <param name="storeId"></param>
    /// <param name="proxyId"></param>
    /// <param name="userId"></param>
    /// <param name="parentId"></param>
    /// <param name="orderId"></param>
    /// <returns></returns>
    private async Task Commission(Entity.TeamBuyProduct e, int teamBuyId, int storeId, int proxyId, int userId, int parentId, int orderId)
    {
        //代理佣金
        await money.Proxy(new ChangeMoneyAndLog { moneyType = MoneyType.拼团返佣, OrderId = orderId, Price = e.ProxyPrice, Type = 1, Uid = proxyId });

        //如果存在邀请人
        if (parentId > 0)
        {
            //用户佣金
            await money.Client(new ChangeMoneyAndLog { moneyType = MoneyType.拼团返佣, OrderId = orderId, Price = e.UserPrice, Type = 1, Uid = parentId });

            //商户佣金 二级
            await money.Store(new ChangeMoneyAndLog { moneyType = MoneyType.拼团返佣, OrderId = orderId, Price = e.StorePrice2, Type = 1, Uid = e.StoreId });
        }
        else
        {
            //商户佣金 一级
            await money.Store(new ChangeMoneyAndLog { moneyType = MoneyType.拼团返佣, OrderId = orderId, Price = e.StorePrice, Type = 1, Uid = e.StoreId });
        }


    }

}
